package umls.interfaces.pubmed.server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;

import metamap.proxy.client.MetamapClient;

public class CachedAbstractMapper extends UncachedMapper implements AbstractMapper {
	public final String cacheDirectory = System.getProperty("user.home")
			+ "/pubmed_result/cache/";

	CachedAbstractMapper(BlockingQueue<MetamapOutput> q, String[] a) {
		super(q, a);
		new File(cacheDirectory).mkdirs();
	}

	CachedAbstractMapper(){
		super();
		new File(cacheDirectory).mkdirs();
	}
	@Override
	public
	List<PubMedAbstractMapped> map(Map<String, String> abstracts) {
		List<PubMedAbstractMapped> result = new LinkedList<PubMedAbstractMapped>();
		for (String id : abstracts.keySet()) {
			FileChannel channel = null;
			FileLock lock = null;
			File f = new File(cacheDirectory + "/" + id + ".txt");

			PubMedAbstractMapped doc = null;
			if (!f.exists()) {
				try {
					channel = new RandomAccessFile(f, "rw").getChannel();
					lock = channel.lock();
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				try {
					doc = new PubMedAbstractMapped(id, MetamapClient
							.blockingQuery(abstracts.get(id)));
					BufferedWriter output = new BufferedWriter(
							new FileWriter(f));
					f.createNewFile();
					for (String row : doc.getAbstract()) {
						output.write(row + "\n");
					}
					output.flush();
					output.close();
					lock.release();
					channel.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			} else {

				doc = new PubMedAbstractMapped(id, readFile(f));
			}
			result.add(doc);
		}

		return result;

	}

	public List<String> readFile(File f) {
		List<String> result = new LinkedList<String>();
		try {
			BufferedReader in = new BufferedReader(new FileReader(f));
			String str;
			while ((str = in.readLine()) != null) {
				result.add(str);
			}
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}
}
